<template>
    <div id="container"></div>
</template>

<script>
import AMapLoader from '@amap/amap-jsapi-loader'
window._AMapSecurityConfig = {
    securityJsCode: 'dd6d2354204cdfa58dba988417e31cf5'
}
import * as THREE from 'three'
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
import * as turf from '@turf/turf'
export default {
    name: 'MapContainer',
    data() {
        return {
            mapObj: null,
            map: null,
            camera:null,
            renderer:null,
            scene:null,
            customCoords:null,
            object:null,
            objPosition: [116.271363, 39.992414],
            centerPoint:turf.point([116.271363, 39.992414]),
            timer:0,
            data:null,
        }
    },
    mounted() {
        this.initMap();
    },
    methods: {
        initMap() {
            AMapLoader.load({
                key: "74f140887d15475e36ecea39c4a583bc",             // 申请好的Web端开发者Key，首次调用 load 时必填
                version: "2.1Beta",      // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
                plugins: [],       // 需要使用的的插件列表，如比例尺'AMap.Scale'等
            }).then((AMap) => {
                this.mapObj = AMap;
                this.map = new AMap.Map("container", {  //设置地图容器id
                    viewMode: "3D",    //是否为3D地图模式
                    zoom: 16,           //初始化地图级别
                    center: [116.271363, 39.992414], //初始化地图中心点位置
                    pitch:50,
                });
                this.map.on('complete', () => {
                    console.log('地图加载完成！')
                    this.initGllayer();
                })
                this.customCoords=this.map.customCoords;
                this.data = this.customCoords.lngLatsToCoords([
            [116.271363, 39.992414],
        ]);
            }).catch(e => {
                console.log(e);
            })
        },
        initGllayer(){
            // 创建 GL 图层
        var gllayer = new AMap.GLCustomLayer({
            // 图层的层级
            zIndex: 10,
            // 初始化的操作，创建图层过程中执行一次。
            init: (gl) => {
                // 这里我们的地图模式是 3D，所以创建一个透视相机，相机的参数初始化可以随意设置，因为在 render 函数中，每一帧都需要同步相机参数，因此这里变得不那么重要。
                // 如果你需要 2D 地图（viewMode: '2D'），那么你需要创建一个正交相机
                this.camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 1 << 30);

                this.renderer = new THREE.WebGLRenderer({
                    context: gl,  // 地图的 gl 上下文
                    // alpha: true,
                    // antialias: true,
                    // canvas: gl.canvas,
                });

                // 自动清空画布这里必须设置为 false，否则地图底图将无法显示
                this.renderer.autoClear = false;
                this.scene = new THREE.Scene();

                // 环境光照和平行光
                var aLight = new THREE.AmbientLight(0xffffff, 0.3);
                var dLight = new THREE.DirectionalLight(0xffffff, 1);
                dLight.position.set(1000, -100, 900);
                this.scene.add(dLight);
                this.scene.add(aLight);

                this.initGltf()
            },
            render: () => {
                // 这里必须执行！！重新设置 three 的 gl 上下文状态。
                this.renderer.resetState();
                // 重新设置图层的渲染中心点，将模型等物体的渲染中心点重置
                // 否则和 LOCA 可视化等多个图层能力使用的时候会出现物体位置偏移的问题
                this.customCoords.setCenter([116.271363, 39.992414]);
                var { near, far, fov, up, lookAt, position } = this.customCoords.getCameraParams();

                // 2D 地图下使用的正交相机
                // var { near, far, top, bottom, left, right, position, rotation } = customCoords.getCameraParams();

                // 这里的顺序不能颠倒，否则可能会出现绘制卡顿的效果。
                this.camera.near = near;
                this.camera.far = far;
                this.camera.fov = fov;
                this.camera.position.set(...position);
                this.camera.up.set(...up);
                this.camera.lookAt(...lookAt);
                this.camera.updateProjectionMatrix();

                // 2D 地图使用的正交相机参数赋值
                // camera.top = top;
                // camera.bottom = bottom;
                // camera.left = left;
                // camera.right = right;
                // camera.position.set(...position);
                // camera.updateProjectionMatrix();

                this.renderer.render(this.scene, this.camera);

                // 这里必须执行！！重新设置 three 的 gl 上下文状态。
                this.renderer.resetState();
            },
        });
        this.map.add(gllayer);
        },
        initGltf() {
            var loader = new GLTFLoader();
            loader.load('https://a.amap.com/jsapi_demos/static/gltf/Duck.gltf', (gltf) => {
                this.object = gltf.scene;
                this.object.scale.set(30, 30, 30)
                this.setRotation({
                    x: 90, y: 0, z: 0
                });
                this.setPosition(this.objPosition);
                this.scene.add(this.object);
                this.startMove();
            });
        },
        setRotation(rotation) {
            var x = Math.PI / 180 * (rotation.x || 0);
            var y = Math.PI / 180 * (rotation.y || 0);
            var z = Math.PI / 180 * (rotation.z || 0);
            this.object.rotation.set(x, y, z);
        },
        setPosition(lnglat) {
            // 对模型的经纬度进行转换
            var position = this.customCoords.lngLatsToCoords([
                lnglat
            ])[0];
            this.object.position.setX(position[0])
            this.object.position.setY(position[1])
        },
        setAngle(angle) {
            var x = this.object.rotation.x;
            var z = this.object.rotation.z;
            var y = Math.PI / 180 * angle;
            this.object.rotation.set(x, y, z);
        },
        startMove() {
            requestAnimationFrame(()=>{
                this.timer += 0.4;
                var pos = turf.transformTranslate(this.centerPoint, 0.3, this.timer).geometry.coordinates;
                var angle = this.timer;
                this.setPosition(pos);
                this.setAngle(angle);
                // 执行地图的渲染
                this.map.render();
                this.startMove();
            });
        }
    },
}
</script>

<style scoped>
.bodyContent {
    width: 100%;
}

#container {
    width: 100%;
    height: 700px;
}
</style>